package com.junxonline.instant.admin.service.monitor.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.junxonline.instant.common.util.common.RedisUtils;
import com.junxonline.instant.dao.entity.model.config.User;
import com.junxonline.instant.dao.entity.model.monitor.OnlineUser;
import com.junxonline.instant.dao.entity.vo.monitor.OnlineUserVO;
import com.junxonline.instant.dao.mapper.config.UserMapper;
import com.junxonline.instant.admin.service.monitor.OnlineUserService;
import com.junxonline.instant.common.constant.RedisConstant;
import com.junxonline.instant.common.entity.common.CommonReqPage;
import com.junxonline.instant.common.entity.common.CommonRespPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户管理接口实现类
 *
 * @author JunX
 * @date 2021-06-24
 */
@Service
@Transactional
public class OnlineUserServiceImpl implements OnlineUserService {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserMapper userMapper;

    /**
     * 查询角色列表
     *
     * @param vo 请求参数
     * @return CommonRespPage<OnlineUser>
     */
    @Override
    public CommonRespPage<OnlineUser> queryList(CommonReqPage<OnlineUserVO> vo) {
        // redis实现分页与条件查询
        Integer pageNum = vo.getPage();
        Integer pageSize = vo.getPageSize();
        Map<String, Object> dataMap = redisUtils.findKeysForPage(RedisConstant.KEY_ONLINE_USER + "*", pageNum, pageSize);
        Set<String> keys = (Set<String>) dataMap.get("records");
        List<OnlineUser> onlineUsers = new ArrayList<>();
        for (String key : keys) {
            Map<Object, Object> map = redisUtils.hmget(key);
            if (map != null && map.size() > 0) {
                OnlineUser onlineUser = new OnlineUser();
                onlineUser.setId((Long) map.get("userId"));
                onlineUser.setUsername((String) map.get("username"));
                onlineUser.setToken((String) map.get("token"));
                onlineUser.setUserIp((String) map.get("userIp"));
                onlineUser.setTargetIp((String) map.get("targetIp"));
                onlineUser.setBrowser((String) map.get("browser"));
                onlineUser.setOs((String) map.get("os"));
                onlineUser.setCreateTime(DateUtil.date((Long) map.get("createTime")));
                onlineUser.setUpdateTime(DateUtil.date((Long) map.get("updateTime")));
                onlineUsers.add(onlineUser);
            }
        }
        // 条件查询
        if (vo.getQueryParams() != null) {
            if (StrUtil.isNotBlank(vo.getQueryParams().getUsername())) {
                String username = vo.getQueryParams().getUsername();
                onlineUsers = onlineUsers.stream().filter(onlineUser -> onlineUser.getUsername().contains(username)).collect(Collectors.toList());
            }
            if (StrUtil.isNotBlank(vo.getQueryParams().getToken())) {
                String token = vo.getQueryParams().getToken();
                onlineUsers = onlineUsers.stream().filter(onlineUser -> onlineUser.getUsername().contains(token)).collect(Collectors.toList());
            }
            if (StrUtil.isNotBlank(vo.getQueryParams().getUserIp())) {
                String userIp = vo.getQueryParams().getUserIp();
                onlineUsers = onlineUsers.stream().filter(onlineUser -> onlineUser.getUserIp().contains(userIp)).collect(Collectors.toList());
            }
            if (StrUtil.isNotBlank(vo.getQueryParams().getTargetIp())) {
                String targetIp = vo.getQueryParams().getTargetIp();
                onlineUsers = onlineUsers.stream().filter(onlineUser -> onlineUser.getTargetIp().contains(targetIp)).collect(Collectors.toList());
            }
        }
        // 排序（按最后访问时间降序）
        onlineUsers = onlineUsers.stream().sorted(Comparator.comparing(OnlineUser::getUpdateTime).reversed()).collect(Collectors.toList());
        Page<OnlineUser> page = new Page<>(vo.getPage(), vo.getPageSize());
        page.setRecords(onlineUsers);
        page.setTotal(onlineUsers.size());
        return CommonRespPage.success(page);
    }

    /**
     * 强制用户下线
     *
     * @param ids 请求参数
     */
    @Override
    public void delete(List<Long> ids) {
        for (Long userId : ids) {
            User user = userMapper.selectById(userId);
            redisUtils.del(RedisConstant.KEY_ONLINE_USER + user.getUsername());
        }
    }

}
